package com.fm.jbsql.sql;

import java.util.logging.Logger;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;

/**
 * Created by IntelliJ IDEA.
 * User: syaroshenko
 * Date: Jul 13, 2006
 * Time: 11:36:27 AM
 * MSSQL implementation of driver specifics. Based on http://jtds.sourceforge.net.
 */

/**
 * MSSQL implementation of driver specifics. Based on http://jtds.sourceforge.net.
 */
public final class DbDriverMSSQL extends DbDriver {
    private static final Logger logger = Logger.getLogger("com.fm.jbsql.sql.DbDriverMSSQL");

    /**
     * Formatted JDBC class string.
     * @return String
     */
    public String getJdbcClass() {
        return "net.sourceforge.jtds.jdbc.Driver";
    }

    /**
     * Formatted driver string.
     * @return String
     */
    public String getJdbcDriver() {
        return "jdbc:jtds:sqlserver";
    }

    /**
     * Formatted connection URL.
     * @param servername Server name
     * @param db Database name
     * @return String
     */
    public String getConnectionString(final String servername, final String db){
        return getJdbcDriver() + "://"+servername+"/"+db;
    }

    /**
     * Driver-dependent table statement.
     * @param isTemp temporary table flag
     * @param checkExisting check existing clause
     * @param tablename table name
     * @param col_array columns array {"name", "nullable", "collation"}
     * @return String
     */
    public String getCreateTableStmt(boolean isTemp, boolean checkExisting, String tablename, String col_array[][]) {
        String columns = "";
        if ( col_array != null ) {
            int len = col_array.length;
            for (int idx = 0; idx < len; idx++) columns += col_array[idx][0] + " " + col_array[idx][2] + " " + col_array[idx][1] + (idx < len-1 ? ", " : "");
        }
        return (checkExisting ? "if object_id('"+ (isTemp? "#" : "") + tablename + "') is null ":"") + (isTemp? "" : "execute('") + "create table " + (isTemp? "#" : "") + tablename + " (" + columns + ")" + (isTemp? "" : "')");
    }

    /**
     * Driver-dependent temporary table symbol.
     * @return String
     */
    public String tempTableSymbol() {
        return "#";
    }

    /**
     * Driver-dependent temporary current date statement.
     * @return String
     */
    public String getDateStmt() {
        return "getdate()";
    }

    /**
     * Driver-dependent commands terminator.
     * @return String
     */
    public String getCmdTerminator() {
        return "go";
    }

    /**
     * Initialize connection: run driver-specific code.
     * @param conn Connection
     * @throws NullPointerException
     */
    public void initConnection(final Connection conn) throws NullPointerException, SQLException {
        if ( conn == null ) throw new NullPointerException();

        // reset quoted identifier
        Statement stmt = conn.createStatement();
        logger.info("Executing query 'set quoted_identifier off' ");
        stmt.executeUpdate("set quoted_identifier off");
        this.checkForWarning(stmt.getWarnings());
        stmt.clearWarnings();
        logger.info("done.");
    }

    /**
     * Return "code before" statement
     * @return String
     */
    public final String getCodeBeforeStart() {
        return "*CODE Before";
    }

    /**
     * Return "code after" statement
     * @return String
     */
    public final String getCodeAfterStart() {
        return "*CODE After";
    }

    /**
     * Return "code end" statement
     * @return String
     */
    public final String getCodeEnd() {
        return "*";
    }

    /**
    * verifies if string is a reserved token
    * @return String
    */
   public int getReservedToken(final String str) {
       if ( str.startsWith(this.getCodeBeforeStart()) ) return ETokenType.ETT_CODE_BEFORE_START;
       if ( str.startsWith(this.getCodeAfterStart()) ) return ETokenType.ETT_CODE_AFTER_START;
       if ( str.startsWith(this.getCodeEnd()) ) return ETokenType.ETT_CODE_END;
       if ( this.getCmdTerminator() == null || str.equalsIgnoreCase(this.getCmdTerminator()) ) return ETokenType.ETT_TERMINATOR;
       return ETokenType.ETT_NONE;
   }

    /**
     * returns "collation" (MSSQL specifics)
     * @return String
     */
    public String getCollationDefaultStmt() {
        return "collate database_default";
    }

    public long getTranCount(final Connection conn) {
        return 0;
    }
}
